﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Threading.Tasks;
using FileSystem.Models;
using FileSystem.Services.IServices;
using FileSystem.Views;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using Xamarin.Forms;

namespace FileSystem.ViewModels {
    /// <summary>
    /// 文件系统页ViewModel
    /// </summary>
    public class FileSystemPageViewModel : ViewModelBase {
        // ******** 构造函数

        /// <summary>
        /// 系统接口
        /// </summary>
        private ISystem _system;

        /// <summary>
        /// 目录项存储
        /// </summary>
        private IDirItemStorage _dirItemStorage;

        /// <summary>
        /// 内容页导航服务
        /// </summary>
        private IContentNavigationService _contentNavigationService;

        public FileSystemPageViewModel(ISystem system, IDirItemStorage dirItemStorage, IContentNavigationService contentNavigationService) {
            _system = system;
            _dirItemStorage = dirItemStorage;
            _contentNavigationService = contentNavigationService;
        }

        // ******** 绑定属性

        /// <summary>
        /// 桌面图标集合
        /// </summary>
        public ObservableCollection<DirItemViewModel> DirItems { get; } =
            new ObservableCollection<DirItemViewModel>();

        /// <summary>
        /// 目录项
        /// </summary>
        public DirItem DirItem {
            get => _dirItem;
            set => Set(nameof(DirItem), ref _dirItem, value);
        }

        /// <summary>
        /// 目录项
        /// </summary>
        private DirItem _dirItem = DirItem.Folder;

        /// <summary>
        /// 地址
        /// </summary>
        public string Address {
            get => _address;
            set {
                Set(nameof(Address), ref _address, value);
                CurrentAddress = value;
            }
        }

        /// <summary>
        /// 地址
        /// </summary>
        private string _address =
            UsersPageViewModel.CurrentUser.UserName + ":\\";

        /// <summary>
        /// 输入名称
        /// </summary>
        public string EntryName {
            get => _entryName;
            set => Set(nameof(EntryName), ref _entryName, value);
        }

        /// <summary>
        /// 输入名称
        /// </summary>
        private string _entryName;

        // ******** 绑定命令

        /// <summary>
        /// 页面显示命令。
        /// </summary>
        private RelayCommand _pageAppearingCommand;

        /// <summary>
        /// 页面显示命令。
        /// </summary>
        public RelayCommand PageAppearingCommand =>
            _pageAppearingCommand ?? (_pageAppearingCommand =
                new RelayCommand(async () =>
                    await PageAppearingCommandFunction()));

        public async Task PageAppearingCommandFunction() {
            if (_isLoaded)
                return;
            _isLoaded = true;

            var dirItems = await _dirItemStorage.GetDirItemsAsync(CurrentAddress);
            foreach (var dirItem in dirItems) {
                if (dirItem.DirItemType == DirItem.FolderConst)
                {
                    dirItem.DirItemType = DirItem.FolderConst;
                    DirItems.Add(new DirItemViewModel
                    {
                        DirItem = dirItem,
                        Image = "Folder.png"
                    });
                }
                else if (dirItem.DirItemType == DirItem.PaperConst)
                {
                    dirItem.DirItemType = DirItem.PaperConst;
                    DirItems.Add(new DirItemViewModel
                    {
                        DirItem = dirItem,
                        Image = "Paper.png"
                    });
                }
            }
        }

        /// <summary>
        /// 添加目录项命令
        /// </summary>
        private RelayCommand _addDirItemCommand;

        /// <summary>
        /// 添加目录项命令
        /// </summary>
        public RelayCommand AddDirItemCommand =>
            _addDirItemCommand ?? (_addDirItemCommand =
                new RelayCommand(async () => AddDirItemCommandFunction()));

        public async Task AddDirItemCommandFunction() {
            var dirItem = new DirItem {DirItemName = EntryName,Location = CurrentAddress, Size = 0};
            if (DirItem.DirItemType == DirItem.FolderConst) {
                dirItem.DirItemType = DirItem.FolderConst;
                DirItems.Add(new DirItemViewModel {
                    DirItem = dirItem, Image = "Folder.png",
                });
            } else if (DirItem.DirItemType == DirItem.PaperConst) {
                dirItem.DirItemType = DirItem.PaperConst;
                DirItems.Add(new DirItemViewModel {
                    DirItem = dirItem, Image = "Paper.png"
                });
            }


            if (DirItem.DirItemType == DirItem.FolderConst)
                await _system.Create(EntryName, DirItemConst.Type.Folder, 0);
            else if (DirItem.DirItemType == DirItem.PaperConst)
                await _system.Create(EntryName, DirItemConst.Type.Paper, 2048);
        }

        /// <summary>
        /// 点击目录项命令
        /// </summary>
        private RelayCommand<DirItem> _clickDirItemCommand;

        /// <summary>
        /// 点击目录项命令
        /// </summary>
        public RelayCommand<DirItem> ClickDirItemCommand =>
            _clickDirItemCommand ?? (_clickDirItemCommand = new RelayCommand<DirItem>(async dirItem => await ClickDirItemCommandFunction(dirItem)));

        public async Task ClickDirItemCommandFunction(DirItem dirItem) {
            if (dirItem.DirItemType == DirItem.FolderConst) {
                if (CurrentAddress == (await _system.GetCurrentUser()).UserName + ":\\") {
                    DirItems.Clear();

                    var dirItems = await _system.Open(dirItem.DirItemName,DirItemConst.Type.Folder,CurrentAddress);
                    if (dirItems != null) {
                        foreach (var dItem in dirItems)
                        {
                            var item = dItem;
                            if (item.DirItemType == DirItem.FolderConst)
                            {
                                item.DirItemType = DirItem.FolderConst;
                                DirItems.Add(new DirItemViewModel
                                {
                                    DirItem = item,
                                    Image = "Folder.png"
                                });
                            }
                            else if (item.DirItemType == DirItem.PaperConst)
                            {
                                item.DirItemType = DirItem.PaperConst;
                                DirItems.Add(new DirItemViewModel
                                {
                                    DirItem = item,
                                    Image = "Paper.png"
                                });
                            }
                        }
                    }

                    Address = Address + dirItem.DirItemName;
                    CurrentAddress = Address;
                    _lastFolderName = dirItem.DirItemName;

                } else {
                    DirItems.Clear();

                    Address = Address + "\\" + dirItem.DirItemName;
                    CurrentAddress = Address;
                    _lastFolderName = dirItem.DirItemName;
                }
            } else {
                await _contentNavigationService.NavigateToAsync(
                    ContentNavigationConstants.PaperPage, dirItem);
            }
        }

        /// <summary>
        /// 返回上级菜单命令
        /// </summary>
        private RelayCommand _returnCommand;

        /// <summary>
        /// 返回上级菜单命令
        /// </summary>
        public RelayCommand ReturnCommand =>
            _returnCommand ?? (_returnCommand = new RelayCommand(async () => await ReturnCommandFunction()));

        public async Task ReturnCommandFunction() {
            if (CurrentAddress !=
                (await _system.GetCurrentUser()).UserName + ":\\") {
                Address = Address.Replace(_lastFolderName, string.Empty);
                CurrentAddress = Address;
                DirItems.Clear();

                var dirItems = await _system.Close(CurrentAddress);
                if (dirItems != null)
                {
                    foreach (var dItem in dirItems)
                    {
                        var item = dItem;
                        if (item.DirItemType == DirItem.FolderConst)
                        {
                            item.DirItemType = DirItem.FolderConst;
                            DirItems.Add(new DirItemViewModel
                            {
                                DirItem = item,
                                Image = "Folder.png"
                            });
                        }
                        else if (item.DirItemType == DirItem.PaperConst)
                        {
                            item.DirItemType = DirItem.PaperConst;
                            DirItems.Add(new DirItemViewModel
                            {
                                DirItem = item,
                                Image = "Paper.png"
                            });
                        }
                    }
                }

            }
        }

        // ******** 公开变量

        public static string CurrentAddress = "";

        // ******** 私有变量
        /// <summary>
        /// NavigationPage
        /// </summary>
        public NavigationPage NavigationPage =>
            _navigationPage ?? (_navigationPage =
                Application.Current.MainPage as NavigationPage);

        /// <summary>
        /// NavigationPage
        /// </summary>
        private NavigationPage _navigationPage;

        /// <summary>
        /// MainPage
        /// </summary>
        public MainPage MainPage =>
            _mainPage ?? (_mainPage = NavigationPage.RootPage as MainPage);

        /// <summary>
        /// MainPage
        /// </summary>
        private MainPage _mainPage;

        /// <summary>
        /// 页面是否已经加载
        /// </summary>
        private volatile bool _isLoaded;

        /// <summary>
        /// 上级文件夹名称
        /// </summary>
        private string _lastFolderName;
    }
}